package cliente;
import comum.*;
import java.rmi.*;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import javax.swing.JOptionPane;

public class SO_PresidenteCliente extends UnicastRemoteObject implements Cliente{

    // Inicialização de instância única de SO_PresidenteCliente
    
    private static SO_PresidenteCliente theSO_PresidenteCliente;
    
    private String ip;
    private Servidor servidor;

    // Construtor privado
    private SO_PresidenteCliente()throws RemoteException{}
    // Getter PresidenteCliente
    public static SO_PresidenteCliente getSO_PresidenteCliente(){
        if (theSO_PresidenteCliente == null) {
            try {
                    theSO_PresidenteCliente = new SO_PresidenteCliente();
            } catch (Exception e) {
                    System.out.println("Trouble: "+ e);
            }
        }
        return theSO_PresidenteCliente;
    }

    public void atualizarTelaDeJogo(){
        /* Chamado por: RN_Partida, VF1
         * Caso de uso: Atualizar Mesa */

        IU_Jogo.getIU_Jogo().atualizarTelaDeJogo();
    }
    
    public void conectarSeAoServidor(){
        /* Chamado por: IU_ConexaoRemota
         * Caso de uso: Entrar em Sala, VF1 */
        Thread t = new Thread(){
            @Override
            public void run(){
                try{
                    setServidor((Servidor) Naming.lookup(getIp()));
                    getServidor().conectarJogador(SO_PresidenteCliente.getSO_PresidenteCliente(), RN_Jogador.getRN_Jogador().getNome());
                }catch(Exception e){
                    IU_Inicial.getIU_Inicial().desabilitarTela();
                    IU_ConexaoRemota.getIU_ConexaoRemota().exibirTela();
                    IU_Inicial.getIU_Inicial().habilitarBotaoConexaoRemota();
                }
            }
        };
        t.start();

        IU_Inicial.getIU_Inicial().desabilitarBotaoConexaoRemota();
        IU_Inicial.getIU_Inicial().habilitarTela();        
        IU_ConexaoRemota.getIU_ConexaoRemota().fecharTela();
    }

    public Servidor getServidor() {
        return servidor;
    }

    public void setServidor(Servidor servidor) {
        this.servidor = servidor;
    }    

    void setIp(String ip) {
        this.ip = ip;
    }

    public String getIp() {
        return ip;
    }   
    
    public void iniciarPrograma(){
        // Jogador, VF1, Iniciar Programa
        IU_Inicial.getIU_Inicial().exibirTela();
    }
    
    public void notificarEspera(HashSet<String> jogadoresConectados){
        // SO_PresidenteServidor, VF1, Notificar Espera
        
        IU_ConexaoRemota.getIU_ConexaoRemota().fecharTela();
        IU_Espera.getIU_Espera().exibirTela();
        IU_Espera.getIU_Espera().exibirJogadoresConectados(jogadoresConectados);
        IU_Inicial.getIU_Inicial().desabilitarTela();

    }
    
    public void desconectarJogadores() throws RemoteException{
        /* Chamado por: IU_Espera, VF1
         * Caso de uso: Sair da espera */
        servidor.desconectarJogadores();
    }
    
    public void notificarErroDeConexao() throws RemoteException {
        Thread t = new Thread(){            
            @Override
            public void run(){
                Object[] options = {"Voltar"};
                JOptionPane.showOptionDialog(IU_ConexaoRemota.getIU_ConexaoRemota(),
                "Um erro ocorreu durante a tentativa de conexao!",
                "Erro de conexao",
                JOptionPane.YES_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,     
                options,  
                options[0]); 
            }
        };
        t.start();
    }

    public void registrarMaoDeCartas(LinkedHashSet<CartaComum> mao) throws RemoteException {
        HashSet<RN_Carta> maoDoJogadorCliente = new HashSet<RN_Carta>();
        for(CartaComum carta : mao){
            maoDoJogadorCliente.add(new RN_Carta(carta));
        }
        RN_Jogador.getRN_Jogador().atualizarMaoDeCartas(maoDoJogadorCliente);
    }

    public void iniciarPartida(Mesa mesa) throws RemoteException {
        RN_Partida.getRN_Partida().atualizarMesa(mesa);
        IU_Espera.getIU_Espera().iniciarPartida();
    }

    public void atualizarMesa(Mesa mesa) throws RemoteException {
        RN_Partida.getRN_Partida().atualizarMesa(mesa);
        IU_Jogo.getIU_Jogo().atualizarTelaDeJogo();
    }

    public void terminarPartida(Mesa mesa, HashMap<String, Integer> ranking) throws RemoteException {
        RN_Partida.getRN_Partida().terminarPartida(mesa);        
        IU_Jogo.getIU_Jogo().desabilitarTela();
        IU_Ranking.getIU_Ranking().exibirTela(ranking);
    }

    public void notificarDesconexao() throws RemoteException {
         Thread t = new Thread(){            
            @Override
            public void run(){        
                IU_ConexaoRemota.getIU_ConexaoRemota().fecharTela();
                IU_Jogo.getIU_Jogo().fecharTela();
                IU_Espera.getIU_Espera().fecharTela();
                IU_Inicial.getIU_Inicial().habilitarTela();
                IU_Inicial.getIU_Inicial().habilitarBotaoConexaoRemota();

                Object[] options = {"OK"};
                JOptionPane.showOptionDialog(IU_Inicial.getIU_Inicial(),
                "Voce foi desconectado!",
                "Desconexao!",
                JOptionPane.YES_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,     
                options,  
                options[0]);
            }
         };
         t.start();
    }
    
    public void fazerJogada(HashSet<CartaComum> selecao) throws RemoteException{
        servidor.fazerJogada(selecao);
    }
}
